package top.dreamix.njitkit.ui.screen.yiban

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Add
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController
import cafe.adriel.lyricist.LocalStrings
import top.dreamix.njitkit.data.yiban.Account
import top.dreamix.njitkit.service.Yiban
import top.dreamix.njitkit.ui.theme.SignedGreen
import top.dreamix.njitkit.ui.theme.UnsignedRed
import top.dreamix.njitkit.ui.viewmodel.YibanUiState
import top.dreamix.njitkit.ui.viewmodel.YibanViewModel
import android.util.Log
import android.widget.Toast
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.LocalIndication
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Switch
import androidx.compose.material3.TextButton
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.draw.clip
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.window.Dialog
import androidx.work.PeriodicWorkRequest
import androidx.work.WorkManager
import kotlinx.coroutines.launch
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromJsonElement

@Composable
fun YibanMainScreen(navController: NavHostController) {
    val vm = viewModel<YibanViewModel>()

    val uiState by vm.uiState.collectAsState()
    MainScreenContent(
        navController = navController,
        uiState = uiState,
        updateUser = vm::updateAccount,
        deleteUser = vm::deleteAccount
    )
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun MainScreenContent(
    navController: NavHostController,
    uiState: YibanUiState,
    updateUser: (Account) -> Unit = {},
    deleteUser: (String) -> Unit = {},
    switchAutoSignIn: (Boolean) -> Unit = {}
) {
    val strings = LocalStrings.current
    var showUserAddDialog by remember { mutableStateOf(false) }
    Scaffold(
        topBar = {
            TopAppBar(
                colors = TopAppBarDefaults.topAppBarColors(
                    //containerColor = MaterialTheme.colorScheme.primaryContainer,
                    titleContentColor = MaterialTheme.colorScheme.primary,
                ),
                title = { Text(strings.yibanTitle) },
                navigationIcon = {
                    IconButton(onClick = { navController.navigateUp() }) {
                        Icon(Icons.AutoMirrored.Filled.ArrowBack, strings.back)
                    }
                },
//                actions = {
//                    IconButton(
//                        onClick = { ... },
//                    ) { ... }
//                }
            )
        }
    ) { innerPadding ->
        if (showUserAddDialog) {
            YibanUserAddDialog(
                onDismissRequest = {showUserAddDialog = false},
                updateUser = updateUser
            )
        }
        Column(
            modifier = Modifier
                .padding(innerPadding)
                .padding(16.dp)
                .verticalScroll(rememberScrollState()),
            verticalArrangement = Arrangement.spacedBy(16.dp)
        ) {
//            Card(
//                modifier = Modifier.fillMaxWidth(),
////                onClick = { showUserAddDialog = true }
//            ) {
//                Row(
//                    modifier = Modifier
//                        .padding(16.dp)
//                        .fillMaxWidth(),
//                        horizontalArrangement = Arrangement.SpaceBetween
//                ) {
//                    Column(
//                        modifier = Modifier.weight(1f),
//                        verticalArrangement = Arrangement.spacedBy(8.dp)
//                    ) {
//                        Text(
//                            strings.yiban.autoSignIn,
//                            fontSize = 16.sp,
//                            fontWeight = FontWeight.Bold
//                        )
//                        Text(
//                            strings.yiban.autoSignInDesc,
//                            fontSize = 12.sp,
//                            fontWeight = FontWeight.Light
//                        )
//                    }
//                    Switch(uiState.isAutoSignIn, switchAutoSignIn)
//                }
//            }
            uiState.accounts.forEach { account ->
                AccountStateCard(
                    navController = navController,
                    account = account,
                    updateUser = updateUser,
                    deleteUser = deleteUser
                )
            }
            Card(
                modifier = Modifier.fillMaxWidth(),
                onClick = { showUserAddDialog = true }
            ) {
                Column(
                    modifier = Modifier
                        .padding(16.dp)
                        .fillMaxWidth(),
                    horizontalAlignment = Alignment.CenterHorizontally,
                ) {
                    Icon(
                        Icons.Filled.Add,
                        strings.createNewAccount,
                        Modifier.size(36.dp)
                    )
                }
            }
        }
    }
}

enum class CardState {
    NORMAL,
    CAPTCHA,
    MESSAGE
}


@OptIn(ExperimentalFoundationApi::class)
@Composable
fun AccountStateCard(
    navController: NavHostController,
    account: Account,
    updateUser: (Account) -> Unit = {},
    deleteUser: (String) -> Unit = {}
) {
    val scope = rememberCoroutineScope()
    val haptics = LocalHapticFeedback.current
    val strings = LocalStrings.current
    val context = LocalContext.current
    var cardState by remember { mutableStateOf(CardState.NORMAL) }
    var accountSigned by remember { mutableStateOf(false) }
    var accountLoading by remember { mutableStateOf(true) }
    var accountAvailable by remember { mutableStateOf(false) }
    var message: @Composable () -> Unit by remember { mutableStateOf({}) }
    var captchaRid: String? by remember { mutableStateOf(null) }
    var captchaMode by remember { mutableStateOf("") }
    var taskMessage by remember { mutableStateOf("") }
    var onClick by remember { mutableStateOf({}) }
    var isShowUserEditDialog by remember { mutableStateOf(false) }
    
    LaunchedEffect(cardState) {
        if(cardState != CardState.NORMAL) return@LaunchedEffect
        var cookie: String = ""
        try {
            cookie = Yiban.SchoolBased.auth(account.access_token)
        } catch (e: Exception) {
            e.printStackTrace()
            try {
                val loginResp = Yiban.login(account.phone, account.password, captchaRid)
                if (loginResp.response == 100) {
                    val data: Yiban.Schema.LoginUserData = Json.decodeFromJsonElement(loginResp.data!!)
                    cookie = Yiban.SchoolBased.auth(data.access_token)
                    updateUser(Account(
                        user_id = data.user.user_id,
                        name = data.user.name,
                        phone = data.user.phone,
                        password = account.password,
                        access_token = data.access_token,
                        cookies = cookie
                    ))
                } else if (loginResp.response == 110 || loginResp.response == 111) {
                    val data: Yiban.Schema.CaptchaData = Json.decodeFromJsonElement(loginResp.data!!)
                    cardState = CardState.CAPTCHA
                    captchaMode = data.mode
                    return@LaunchedEffect
                } else {
                    message = { Text(loginResp.message) }
                    cardState = CardState.MESSAGE
                    return@LaunchedEffect
                }
            } catch (e: Exception) {
                e.printStackTrace()
                message = {
                    Text(e.localizedMessage ?: "Error happened when login")
                }
                cardState = CardState.MESSAGE
                return@LaunchedEffect
            }
        }
        updateUser(
            account.copy(cookies = cookie)
        )
        if (cookie.isNotEmpty()) {
            val task = Yiban.SchoolBased.getNightAttendanceTask(cookie)
            if(task.code == 0) {
                task.data!!
                val state = task.data.State
                if(state == 0) {
                    // 可签到状态
                    accountAvailable = true
                    accountLoading = false
                    accountSigned = false
                    taskMessage = if(task.data.Msg != "") task.data.Msg else "未签到"
                } else if(state == 1) {
                    // 未到签到时间
                    accountAvailable = false
                    accountLoading = false
                    accountSigned = false
                    taskMessage = task.data.Msg
                } else if(state == 2) {
                    // 无需签到
                    accountAvailable = false
                    accountLoading = false
                    accountSigned = true
                    taskMessage = task.data.Msg
                } else if(state == 3) {
                    // 已签到状态
                    accountAvailable = false
                    accountLoading = false
                    accountSigned = true
                    taskMessage = task.data.Msg
                }
                onClick = {
                    scope.launch {
                        accountLoading = true
                        val resp = Yiban.SchoolBased.nightAttendanceSignIn(cookie, task.data)
                        if (resp.code == 0) {
                            accountAvailable = false
                            accountLoading = false
                            accountSigned = true
                            taskMessage = if(resp.msg != "") resp.msg else "签到成功"
                        } else {
                            message = { Text(resp.msg) }
                            cardState = CardState.MESSAGE
                        }
                    }
                }
            }
        } else {
            message = { Text("Cookie is empty") }
            cardState = CardState.MESSAGE
        }
    }
    val containerColor = when {
        accountLoading -> MaterialTheme.colorScheme.primaryContainer
        accountSigned -> SignedGreen
        else -> UnsignedRed
    }
    Card(
        modifier = Modifier
//            .apply{ if(cardState != CardState.CAPTCHA) height(80.dp) } // 设置不恰当的高度可能导致验证码webview无法显示
            .clip(RoundedCornerShape(16.dp)) // 关键：先裁剪边界
            .combinedClickable(
                interactionSource = remember { MutableInteractionSource() },
                indication = LocalIndication.current,
                onClick = {
                    if (accountAvailable) onClick() else Log.w(
                        "Yiban",
                        "Account Card is clicked while it is not available"
                    )
                },
                onLongClick = {
                    haptics.performHapticFeedback(HapticFeedbackType.LongPress)
                    isShowUserEditDialog = true
                },
            )
            .fillMaxWidth(),
        colors = CardDefaults.cardColors(
            containerColor = containerColor
        )
    ) {
        when (cardState) {
            CardState.NORMAL -> {
                if(accountLoading) {
                    Column(
                        Modifier
                            .padding(16.dp)
                            .fillMaxWidth(),
                        horizontalAlignment = Alignment.CenterHorizontally,
                        verticalArrangement = Arrangement.Center
                    ) {
                        CircularProgressIndicator()
                    }
                    return@Card
                }
                Column(Modifier.padding(16.dp)) {
                    Text(
                        text = account.name,
                        fontWeight = FontWeight.Bold,
                        fontSize = 16.sp
                    )
                    Spacer(Modifier.height(4.dp))
                    Text(
                        text = taskMessage,
                        fontWeight = FontWeight.Light,
                        fontSize = 12.sp
                    )
                }
            }
            CardState.CAPTCHA -> {
                ShuMeiCaptchaScreen(
                    mode = captchaMode,
                    onReady = { Log.i("ShuMei", "ShuMei called onresult OnReady") },
                    onSuccess = {
                        if (it["rid"] is String) {
                            captchaRid = it["rid"] as String
                            cardState = CardState.NORMAL
                        } else {
                            message = { Text("Strings.验证码返回的rid无效") }
                            cardState = CardState.MESSAGE
                        }
                    },
                    onError = { code, msg ->
                        message = { Text(msg) }
                        cardState = CardState.MESSAGE
                        Log.i("ShuMei", "ShuMei called onresult OnError: code: $code, message: $msg")
                    }
                )
            }
            CardState.MESSAGE -> {
                Box(Modifier.padding(16.dp)) {
                    message()
                }
            }
        }
    }
    if(isShowUserEditDialog) {
        Dialog(
            onDismissRequest = {isShowUserEditDialog = false}
        ) {
            Card {
                Column(
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(16.dp)
                ) {
                    TextButton(
                        onClick = { deleteUser(account.phone) }
                    ) {
                        Text(strings.delete, color = MaterialTheme.colorScheme.error)
                    }
                    TextButton(
                        onClick = {
                            scope.launch {
                                try {
                                    val task =
                                        Yiban.SchoolBased.getNightAttendanceTask(account.cookies).data!!
                                    val resp = Yiban.SchoolBased.nightAttendanceSignIn(account.cookies, task)
                                    Toast.makeText(context, resp.msg, Toast.LENGTH_SHORT).show()
                                } catch (e: Exception) {
                                    Toast.makeText(context, e.message, Toast.LENGTH_LONG).show()
                                }
                                isShowUserEditDialog = false
                            }
                        }
                    ) {
                        Text(strings.forceSignIn)
                    }
                }
            }
        }
    }
}

private fun configureAutoSignInWork(run: Boolean) {
    
}

@Preview
@Composable
fun PreviewMainContent() {
    MainScreenContent(
        navController = NavHostController(LocalContext.current),
        uiState = YibanUiState(
            accounts = listOf(
                Account(10001, "张三", "12222222222", "ewew4e8w9weqq", cookies = ""),
                Account(10002, "李四", "13333333333", "ewew4e8w9weqq", cookies = ""),
                Account(10003, "王五", "14444444444", "asdfasdfasdf", cookies = "")
            )
        )
    )
}
